﻿using System;
using System.Collections.Generic;
using System.Linq;
using Autodesk.Revit.DB;
using Autodesk.Revit.DB.Electrical;
using YArchitech.Revit.Electric.Common;

namespace Model
{
	public class PathwayCheck
	{
		public IList<Element> GetPathwayDevices(Element device, SearchDeviceType findType)
		{
			List<Element> list = new List<Element>();
			this.SearchDevice(device);
			if (this.allEquipment.Count > 0)
			{
				if ((findType & SearchDeviceType.CableTray) == SearchDeviceType.CableTray)
				{
					List<Element> collection = (from ct in this.allEquipment
					where ct is CableTray
					select ct).ToList<Element>();
					list.AddRange(collection);
				}
				if ((findType & SearchDeviceType.Conduit) == SearchDeviceType.Conduit)
				{
					List<Element> collection2 = (from cd in this.allEquipment
					where cd is Conduit
					select cd).ToList<Element>();
					list.AddRange(collection2);
				}
				if ((findType & SearchDeviceType.CableTrayFitting) == SearchDeviceType.CableTrayFitting)
				{
					List<Element> collection3 = (from cf in this.allEquipment
					where cf.Category.Id.IntegerValue.ToString() == "OST_CableTrayFitting"
					select cf).ToList<Element>();
					list.AddRange(collection3);
				}
				if ((findType & SearchDeviceType.ConduitFitting) == SearchDeviceType.ConduitFitting)
				{
					List<Element> collection4 = (from cf in this.allEquipment
					where cf.Category.Id.IntegerValue.ToString() == "OST_ConduitFitting"
					select cf).ToList<Element>();
					list.AddRange(collection4);
				}
				if ((findType & SearchDeviceType.Device) == SearchDeviceType.Device)
				{
					List<Element> collection5 = (from ct in this.allEquipment
					where ct is FamilyInstance
					select ct).ToList<Element>();
					list.AddRange(collection5);
				}
			}
			return list;
		}

		private void SearchDevice(Element device)
		{
			foreach (Element device2 in this.GetConnectedDevices(device))
			{
				this.SearchDevice(device2);
			}
		}

		private List<Element> GetConnectedDevices(Element device)
		{
			List<Connector> connectors = new List<Connector>();
			List<Element> list = new List<Element>();
			if (device is CableTray)
			{
				CableTray cableTray = device as CableTray;
				connectors = this.GetCableTrayConnectors(cableTray);
			}
			else if (device is Conduit)
			{
				connectors = RevitUtils.GetConduitConnectors(device as Conduit);
			}
			else if (device is FamilyInstance || device.Category.Id.IntegerValue.ToString() == "OST_CableTrayFitting" || device.Category.Id.IntegerValue.ToString() == "OST_ConduitFitting")
			{
				connectors = this.GetFamilyInstanceConnectors(device);
			}
			foreach (Element element in this.GetDevicesByConnectors(connectors))
			{
				if (!this.allEquipment.Contains(element, this.equipmentComparer))
				{
					this.allEquipment.Add(element);
					list.Add(element);
				}
			}
			return list;
		}

		private List<Element> GetDevicesByConnectors(List<Connector> connectors)
		{
			List<Element> list = new List<Element>();
			foreach (Connector connector in connectors)
			{
				ConnectorSet allRefs = connector.AllRefs;
				if (allRefs.Size > 0)
				{
					foreach (object obj in allRefs)
					{
						Connector connector2 = (Connector)obj;
						bool flag = false;
						Element owner = connector2.Owner;
						if (owner is CableTray)
						{
							flag = true;
						}
						else if (owner is Conduit)
						{
							flag = true;
						}
						else if (owner is FamilyInstance || owner.Category.Id.IntegerValue.ToString() == "OST_CableTrayFitting" || owner.Category.Id.IntegerValue.ToString() == "OST_ConduitFitting")
						{
							flag = true;
						}
						if (flag && !list.Contains(owner, this.equipmentComparer))
						{
							list.Add(owner);
						}
					}
				}
			}
			return list;
		}

		public List<Connector> GetFamilyInstanceConnectors(Element element)
		{
			List<Connector> list = new List<Connector>();
			FamilyInstance familyInstance = element as FamilyInstance;
			if (familyInstance == null)
			{
				return list;
			}
			ConnectorSetIterator connectorSetIterator = familyInstance.MEPModel.ConnectorManager.Connectors.ForwardIterator();
			while (connectorSetIterator.MoveNext())
			{
				object obj = connectorSetIterator.Current;
				Connector item = obj as Connector;
				list.Add(item);
			}
			return list;
		}

		private List<Connector> GetCableTrayConnectors(CableTray cableTray)
		{
			List<Connector> list = new List<Connector>();
			ConnectorSetIterator connectorSetIterator = cableTray.ConnectorManager.Connectors.ForwardIterator();
			while (connectorSetIterator.MoveNext())
			{
				object obj = connectorSetIterator.Current;
				Connector item = obj as Connector;
				if (!list.Contains(item))
				{
					list.Add(item);
				}
			}
			return list;
		}

		private EquipmentComparer equipmentComparer = new EquipmentComparer();

		private List<Element> allEquipment = new List<Element>();
	}
}
